package me.zhengjie.tools.service.impl

import com.alipay.api.AlipayClient
import com.alipay.api.DefaultAlipayClient
import com.alipay.api.response.AlipayTradePagePayResponse
import com.alipay.api.response.AlipayTradeWapPayResponse
import com.alipay.api.request.AlipayTradeWapPayRequest
import com.alipay.api.request.AlipayTradePagePayRequest

import me.zhengjie.common.exception.BadRequestException
import me.zhengjie.tools.service.AlipayService
import me.zhengjie.tools.domain.AlipayConfig
import me.zhengjie.tools.domain.vo.TradeVo
import me.zhengjie.tools.repository.AlipayRepository
import org.springframework.cache.annotation.CacheConfig
import org.springframework.cache.annotation.CachePut
import org.springframework.cache.annotation.Cacheable
import org.springframework.stereotype.Service
import org.springframework.transaction.annotation.Propagation
import org.springframework.transaction.annotation.Transactional
import java.util.*
import java.util.function.Supplier

/**
 * @author Kuki Wu
 * @date 2018-12-31
 */
@Service
@CacheConfig(cacheNames = ["alipay"])
@Transactional(propagation = Propagation.SUPPORTS, readOnly = true, rollbackFor = [Exception::class])
class AlipayServiceImpl(alipayRepository: AlipayRepository) : AlipayService {
    private val alipayRepository: AlipayRepository

    init {
        this.alipayRepository = alipayRepository
    }

    @Throws(Exception::class)
    override fun toPayAsPC(alipay: AlipayConfig?, trade: TradeVo?): String {
        if (alipay!!.id == null) {
            throw BadRequestException("请先添加相应配置，再操作")
        }
        val alipayClient: AlipayClient = DefaultAlipayClient(
            alipay!!.gatewayUrl,
            alipay!!.appID,
            alipay!!.privateKey,
            alipay!!.format,
            alipay.charset,
            alipay!!.publicKey,
            alipay!!.signType
        )

//        double money = Double.parseDouble(trade.getTotalAmount());

        // 创建API对应的request(电脑网页版)
        val request = AlipayTradePagePayRequest()

        // 订单完成后返回的页面和异步通知地址
        request.setReturnUrl(alipay.returnUrl)
        request.setNotifyUrl(alipay.notifyUrl)
        // 填充订单参数
        request.setBizContent(
            "{" +
                    "    \"out_trade_no\":\"" + trade!!.outTradeNo + "\"," +
                    "    \"product_code\":\"FAST_INSTANT_TRADE_PAY\"," +
                    "    \"total_amount\":" + trade.totalAmount + "," +
                    "    \"subject\":\"" + trade.subject + "\"," +
                    "    \"body\":\"" + trade.body + "\"," +
                    "    \"extend_params\":{" +
                    "    \"sys_service_provider_id\":\"" + alipay.sysServiceProviderId + "\"" +
                    "    }" +
                    "  }"
        ) //填充业务参数
        // 调用SDK生成表单, 通过GET方式，口可以获取url
        return alipayClient.pageExecute<AlipayTradePagePayResponse>(request, "GET").getBody()
    }

    @Throws(Exception::class)
    override fun toPayAsWeb(alipay: AlipayConfig?, trade: TradeVo?): String {
        if (alipay!!.id == null) {
            throw BadRequestException("请先添加相应配置，再操作")
        }
        val alipayClient: AlipayClient = DefaultAlipayClient(
            alipay.gatewayUrl,
            alipay.appID,
            alipay.privateKey,
            alipay.format,
            alipay.charset,
            alipay.publicKey,
            alipay.signType
        )
        val money: Double = trade!!.totalAmount!!.toDouble()
        if (money <= 0 || money >= 5000) {
            throw BadRequestException("测试金额过大")
        }
        // 创建API对应的request(手机网页版)
        val request = AlipayTradeWapPayRequest()
        request.setReturnUrl(alipay.returnUrl)
        request.setNotifyUrl(alipay.notifyUrl)
        request.setBizContent(
            "{" +
                    "    \"out_trade_no\":\"" + trade.outTradeNo + "\"," +
                    "    \"product_code\":\"FAST_INSTANT_TRADE_PAY\"," +
                    "    \"total_amount\":" + trade.totalAmount + "," +
                    "    \"subject\":\"" + trade.subject + "\"," +
                    "    \"body\":\"" + trade.body + "\"," +
                    "    \"extend_params\":{" +
                    "    \"sys_service_provider_id\":\"" + alipay.sysServiceProviderId + "\"" +
                    "    }" +
                    "  }"
        ) //填充业务参数
        return alipayClient.pageExecute<AlipayTradeWapPayResponse>(request, "GET").getBody()
    }

    @Cacheable(key = "'1'")
    override fun find(): AlipayConfig? {
        val alipayConfig: Optional<AlipayConfig?> = alipayRepository.findById(1L)
        return alipayConfig.orElseGet(Supplier { AlipayConfig() })
    }

    @CachePut(key = "'1'")
    @Transactional(rollbackFor = [Exception::class])
    override fun update(alipayConfig: AlipayConfig?): AlipayConfig {
        return alipayRepository.save(alipayConfig!!)
    }
}